﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BGELanguageEditor
{
    public partial class MainForm : Form
    {
        private string[] bgeTexts;
        private string folder;

        private string textFile;

        private List<string[]> allFiles = new List<string[]>();
        private string[] currentLines;
        private List<KeyValuePair<int, string>> bgeSearchLines = new List<KeyValuePair<int, string>>();
        private List<EqualLine> equalLines = new List<EqualLine>();

        private Encoding encoding;

        public MainForm()
        {
            InitializeComponent();

            string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string bgeData = Path.Combine(appData, "BeyondGoodEvil_Translation");
            string userData = Path.Combine(appData, "user.data");
            if (Directory.Exists(bgeData))
            {
                // read data
                if (File.Exists(userData))
                {
                    using (Stream s = File.OpenRead(userData))
                    {
                        BinaryReader reader = new BinaryReader(s);
                        folder = reader.ReadString();
                    }
                }
            }
            else
            {
                Directory.CreateDirectory(bgeData);
            }

            string ass = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            ass = Path.GetDirectoryName(Path.GetDirectoryName(ass));
            ass = Path.Combine(ass, "BGE");

            if (Directory.Exists(ass))
            {
                folder = ass;
            }

            if (string.IsNullOrEmpty(folder))
            {
                if (!GetFolderFromUser(out folder))
                {
                    MessageBox.Show("No folder loaded, application chosing");
                    this.Close();
                }
            }

            if (File.Exists(userData))
            {
                File.Delete(userData);
            }
            using (Stream s = File.Create(userData))
            {
                BinaryWriter writer = new BinaryWriter(s);
                writer.Write(folder);
            }

            List<string> bge = new List<string>();
            DirectoryInfo dir = new DirectoryInfo(folder);
            FileInfo[] files = dir.GetFiles();
            for (int i = 0; i < files.Length; i++)
            {
                FileInfo f = files[i];
                if (f.Extension.ToLower() == ".txt")
                {
                    bge.Add(f.Name);

                    // load the data
                    List<string> txtLine = new List<string>();
                    using (Stream s = File.OpenRead(f.FullName))
                    {
                        using (StreamReader reader = new StreamReader(s, Encoding.Default))
                        {
                            encoding = reader.CurrentEncoding;

                            while(!reader.EndOfStream)
                            {
                                txtLine.Add(reader.ReadLine());
                            }
                        }
                    }

                    allFiles.Add(txtLine.ToArray());
                }
            }

            bgeTexts = bge.ToArray();
        }

        private static bool GetFolderFromUser(out string f)
        {
            using (FolderBrowserDialog browser = new FolderBrowserDialog())
            {
                if (browser.ShowDialog() == DialogResult.OK)
                {
                    f = browser.SelectedPath;
                    return true;
                }
                else
                {
                    f = "";
                    return false;
                }
            }
        }

        private void txt_Search_TextChanged(object sender, EventArgs e)
        {
            bgeSearchLines.Clear();
            bgeSearchLines.Capacity = 0;

            if (currentLines == null)
            {
                return;
            }

            string searchLine = txt_Search.Text.ToLower();
            for (int i = 0; i < currentLines.Length; i++)
            {
                string line = currentLines[i];
                string lined = line.ToLower();

                if (lined.Contains(searchLine))
                {
                    KeyValuePair<int, string> str = new KeyValuePair<int, string>(i, line);
                    bgeSearchLines.Add(str);
                }
            }

            list_Search.DataSource = null;
            list_Search.DataSource = bgeSearchLines;
            list_Search.Visible = true;
        }

        private void list_Search_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (list_Search.SelectedValue == null)
            {
                return;
            }

            KeyValuePair<int, string> selected = (KeyValuePair<int, string>)list_Search.SelectedValue;
            list_Search.Visible = false;
            list_lines.SelectedIndex = selected.Key;
        }

       
        private void UnloadText()
        {
            if (bgeSearchLines != null)
            {
                bgeSearchLines.Clear();
                bgeSearchLines.Capacity = 0;
            }
        }

        private void goToLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChooseLine choose = new ChooseLine();
            choose.Max = list_lines.Items.Count;
            if (choose.ShowDialog() == DialogResult.OK)
            {
                list_lines.SelectedIndex = choose.LineTo - 1;
            }
        }

        private void list_lines_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (list_lines.SelectedIndex == -1)
            {
                return;
            }

            lbl_line.Text = (list_lines.SelectedIndex + 1).ToString();

            equalLines.Clear();

            string txt;
            if (list_lines.DataSource is string[])
            {
                txt = ((string[])list_lines.DataSource)[list_lines.SelectedIndex];
            }
            else
            {
                txt = ((List<string>)list_lines.DataSource)[list_lines.SelectedIndex];
            }

            // search for this text in other files
            if (txt != "¤" && !string.IsNullOrEmpty(txt))
            {
                for (int i = 0; i < allFiles.Count; i++)
                {
                    string[] allLines = allFiles[i];
                    for (int j = 0; j < allLines.Length; j++)
                    {
                        string s = allLines[j];
                        if (s == txt)
                        {
                            equalLines.Add(new EqualLine(j, i));
                        }
                    }
                }
            }
            txt_line.Text = txt;
        }

        private void txt_line_TextChanged(object sender, EventArgs e)
        {
            if (list_lines.SelectedIndex == -1)
            {
                return;
            }

            // change the current and every file else
            for (int i = 0; i < equalLines.Count; i++)
            {
                EqualLine l = equalLines[i];

                string[] lines = allFiles[l.file];
                lines[l.line] = txt_line.Text;
            }
            currentLines[list_lines.SelectedIndex] = txt_line.Text;
        }


        private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (OpenFileForm form = new OpenFileForm(bgeTexts))
            {
                if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    // unload current text
                    UnloadText();

                    textFile = bgeTexts[form.SelectedText];
                    currentLines = allFiles[form.SelectedText];
                    list_lines.DataSource = currentLines;

                    lbl_loaded.Text = textFile;
                }
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // save everything!
            for (int i = 0; i < allFiles.Count; i++)
            {
                string[] lines = allFiles[i];
                string fullPath = Path.Combine(folder, bgeTexts[i]);

                FileInfo f = new FileInfo(fullPath);
                if (f.IsReadOnly)
                {
                    f.IsReadOnly = false;
                }
                f.Delete();

                using (FileStream stream = new FileStream(fullPath, FileMode.Create))
                {
                    using (StreamWriter writer = new StreamWriter(stream, encoding))
                    {
                        for (int j = 0; j < lines.Length; j++)
                        {
                            writer.WriteLine(lines[j]);
                        }

                        writer.Flush();
                        stream.Flush();
                    }
                }
            }
        }

        private void findToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        
    }
}
